import time
import aiohttp
import asyncio
from bs4 import BeautifulSoup
import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Referer': 'https://movie.douban.com/top250'
}

async def fetch_page(session, url):
    """异步获取单个网页内容"""
    # 使用异步上下文管理器发送GET请求
    async with session.get(url, headers=headers) as response:
        # 等待响应内容返回，返回的是网页的HTML文本
        return await response.text()

async def parse_html(html):
    """解析单个网页的电影数据"""
    # 创建BeautifulSoup对象，解析HTML内容
    soup = BeautifulSoup(html, 'lxml')
    movies = []
    # 遍历页面中的每个电影项
    for item in soup.select('div.item'):
        # 提取电影标题
        title = item.select_one('.title').text
        # 提取电影评分
        rating = item.select_one('.rating_num').text
        # 提取电影简介，部分电影可能没有简介，所以需要异常处理
        try:
            quote = item.select_one('.inq').text
        except:
            quote = ''
        # 提取电影详情页链接
        link = item.select_one('a')['href']
        # 将电影信息存储为字典
        movies.append({
            'title': title,
            'rating': rating,
            'quote': quote,
            'link': link
        })
    # 返回当前页面解析出的所有电影数据
    return movies

async def main():
    # 记录程序开始时间
    start_time = time.time()
    # 构造豆瓣电影Top 250的URL
    base_url = "https://movie.douban.com/top250?start={}"
    # 生成前10页的请求地址
    urls = [base_url.format(i * 25) for i in range(10)]
    # 初始化异步HTTP会话，用于发送网络请求
    async with aiohttp.ClientSession() as session:
        # 为每个URL创建一个异步任务，用于发送网络请求
        tasks = [fetch_page(session, url) for url in urls]
        # 并发执行所有异步任务，获取所有页面的HTML内容
        html_pages = await asyncio.gather(*tasks)
        # 初始化一个列表，用于存储所有电影数据
        all_movies = []
        # 遍历每个页面的HTML内容，解析并提取电影数据
        for html in html_pages:
            # 调用解析函数，解析当前页面的HTML内容
            movies = await parse_html(html)
            # 将当前页面的电影数据添加到总列表中
            all_movies.extend(movies)
        # 打印所有电影数据
        for movie in all_movies:
            print(f"电影名称：{movie['title']}, 评分：{movie['rating']},"
                  f" 简介：{movie['quote']}, 链接：{movie['link']}")
        # 记录程序结束时间
        end_time = time.time()
        # 计算并打印程序运行时间
        print(f"异步爬虫运行时间：{end_time - start_time}秒")

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())